package cn.dakaqi.services.impl;

import cn.dakaqi.dao.ActivitySignDao;
import cn.dakaqi.entities.*;
import cn.dakaqi.entities.user.Volunteer;
import cn.dakaqi.services.*;
import cn.dakaqi.services.user.VolunteerService;
import cn.dakaqi.utils.BaseDAO;
import cn.dakaqi.utils.Clock;
import cn.dakaqi.utils.DKQConstant;
import cn.dakaqi.utils.DateUtil;
import cn.dakaqi.utils.exception.ServiceRuntimeException;
import cn.dakaqi.utils.rongYun.PushActivityMesssage;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;

import java.util.List;
import java.util.Map;

/**
 * Created by chunyang on 2016/4/18.
 */
@Component(value = "activitySignService")
@Transactional
public class ActivitySignServiceImpl implements ActivitySignService
{
    @Autowired
    ActivitySignDao activitySignDao;
    @Autowired
    ActivityService activityService;
    @Autowired
    VolunteerService volunteerService;
    @Autowired
    GroupService groupService;
    @Autowired
    GroupVolunteerService groupVolunteerService;
    @Autowired
    BaseDAO baseDAO;
    @Override
    public void save(String param) throws ServiceRuntimeException
    {
        JSONObject jsonObject = JSON.parseObject(param);
        Long volunteerId = jsonObject.getLong("volunteerId");
        Long activityId = jsonObject.getLong("activityId");
        double lng = jsonObject.getLong("lng");
        double lat = jsonObject.getLong("lat");
        ActivitySign activitySign = new ActivitySign();
        activitySign.setVolunteer(new Volunteer(volunteerId));
        activitySign.setActivity(new Activity(activityId));
        activitySign.setCreateTime(Clock.DEFAULT.getCurrentDate());
        activitySign.setLng(lng);
        activitySign.setLat(lat);
        this.save(activitySign);
    }

    @Override
    public void save(ActivitySign activitySign) throws ServiceRuntimeException
    {
        //保存公益记录
        this.activitySignDao.save(activitySign);

        //更新活动的累计时间
        Activity activity = activitySign.getActivity();
        activity.setTimes(activity.getTimes()+activitySign.getTimes());
        activity.setAttends(activity.getAttends()+1);
        this.activityService.update(activity);

        //更新当前志愿者的累计时间
        Volunteer volunteer = activitySign.getVolunteer();
        if(null != activitySign.getActivity().getPlatform() && !"null".equals(activitySign.getActivity().getPlatform()) && StringUtils.isNotBlank(activitySign.getActivity().getPlatform()))
            volunteer.setvTimes(volunteer.getvTimes() + activitySign.getTimes());
        else
            volunteer.setTimes(volunteer.getTimes() + activitySign.getTimes());

        volunteer.setActs(volunteer.getActs() + 1);
        volunteer.setLastJoinActDate(DateUtil.getToday());
        this.volunteerService.updateVolunteer(volunteer);

        //更新社团的累计时间
        Group group = activitySign.getActivity().getGroup();
        group.setTimes(group.getTimes()+activitySign.getTimes());
        this.groupService.update(group);

        //更新当前会员在当前社团的累计完成的公益时间
        GroupVolunteer groupVolunteer = this.groupVolunteerService.findByMemberAndGroup(volunteer.getMemberCode(), DKQConstant.APPLY_STATUS_OK ,group.getGroupCode());
        if(null != groupVolunteer)
        {
            groupVolunteer.setTimes(groupVolunteer.getTimes()+activitySign.getTimes());
            this.groupVolunteerService.update(groupVolunteer);
        }
        if(activitySign.getTimes()>0)
        {
            PushActivityMesssage.getInstance().activityDiary(activitySign.getActivity().getName(), activitySign.getVolunteer().getMemberCode(), activitySign.getActivity().getActivityCode(), activitySign.getActivity().getGroup().getGroupCode());
            PushActivityMesssage.getInstance().commentVolunteerList(activitySign.getVolunteer().getRealName(), activitySign.getActivity().getMonitor().getMemberCode(), activitySign.getActivity().getActivityCode(),activitySign.getActivity().getName());
        }
    }

    @Override
    public void update(ActivitySign activitySign) throws ServiceRuntimeException
    {
        //保存公益记录
        this.activitySignDao.save(activitySign);
    }

    @Override
    public ActivitySign updateTimes(ActivitySign activitySign, int oldTime) throws ServiceRuntimeException
    {
        //保存公益记录
        this.activitySignDao.save(activitySign);
        if(activitySign.getTimes()>0)
        {
            //更新活动的累计时间
            Activity activity = activitySign.getActivity();
            activity.setTimes(activity.getTimes()+activitySign.getTimes()-oldTime);
            this.activityService.update(activity);

            //更新当前志愿者的累计时间
            Volunteer volunteer = activitySign.getVolunteer();

            if(null != activitySign.getActivity().getPlatform() && !"null".equals(activitySign.getActivity().getPlatform()) && StringUtils.isNotBlank(activitySign.getActivity().getPlatform()))
                volunteer.setvTimes(volunteer.getvTimes() + activitySign.getTimes() - oldTime);
            else
                volunteer.setTimes(volunteer.getTimes()+activitySign.getTimes()-oldTime);

            volunteer.setLastJoinActDate(DateUtil.getToday());
            this.volunteerService.updateVolunteer(volunteer);

            //更新社团的累计时间
            Group group = activitySign.getActivity().getGroup();
            group.setTimes(group.getTimes()+activitySign.getTimes()-oldTime);
            this.groupService.update(group);

            //更新当前会员在当前社团的累计完成的公益时间
            GroupVolunteer groupVolunteer = this.groupVolunteerService.findByMemberAndGroup(volunteer.getMemberCode(), DKQConstant.APPLY_STATUS_OK ,group.getGroupCode());
            if(null != groupVolunteer)
            {
                groupVolunteer.setTimes(groupVolunteer.getTimes()+activitySign.getTimes()-oldTime);
                this.groupVolunteerService.update(groupVolunteer);
            }
            if(activitySign.getTimes()>0)
            {
                //如果签到次数>2时，则不在进行提示


                PushActivityMesssage.getInstance().activityDiary(activitySign.getActivity().getName(), activitySign.getVolunteer().getMemberCode(), activitySign.getActivity().getActivityCode(), activitySign.getActivity().getGroup().getGroupCode());
                PushActivityMesssage.getInstance().commentVolunteerList(activitySign.getVolunteer().getRealName(), activitySign.getActivity().getMonitor().getMemberCode(), activitySign.getActivity().getActivityCode(), activitySign.getActivity().getName());
            }
        }

        return activitySign;
    }

    @Override
    public Page<ActivitySign> queryByMember(String memberCode, int pageNumber) throws ServiceRuntimeException
    {
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        PageRequest pageRequest = new PageRequest(pageNumber - 1, 20, sort);
        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("volunteer.memberCode", new SearchFilter("volunteer.memberCode", SearchFilter.Operator.EQ, memberCode));
        Specification<ActivitySign> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivitySign.class);
        return this.activitySignDao.findAll(spec, pageRequest);
    }

    @Override
    public Page<ActivitySign> queryByMember(Long volunteerId, int pageNumber) throws ServiceRuntimeException
    {
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        PageRequest pageRequest = new PageRequest(pageNumber - 1, 20, sort);

        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("volunteer.id", new SearchFilter("volunteer.id", SearchFilter.Operator.EQ, volunteerId));
        Specification<ActivitySign> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivitySign.class);
        return this.activitySignDao.findAll(spec, pageRequest);
    }

    @Override
    public Page<ActivitySign> queryByActivity(String activityCode, int pageNumber) throws ServiceRuntimeException
    {
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        PageRequest pageRequest = new PageRequest(pageNumber - 1, 20, sort);
        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("activity.activityCode", new SearchFilter("activity.activityCode", SearchFilter.Operator.EQ, activityCode));
        Specification<ActivitySign> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivitySign.class);
        return this.activitySignDao.findAll(spec, pageRequest);
    }

    @Override
    public Page<ActivitySign> queryUnCommentByActivityCode(String activityCode, int pageNumber) throws ServiceRuntimeException
    {
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        PageRequest pageRequest = new PageRequest(pageNumber - 1, 20, sort);
        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("activity.activityCode", new SearchFilter("activity.activityCode", SearchFilter.Operator.EQ, activityCode));
        filters.put("hasCommnet", new SearchFilter("hasCommnet", SearchFilter.Operator.EQ, DKQConstant.COMMENT_NO));
        Specification<ActivitySign> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivitySign.class);
        return this.activitySignDao.findAll(spec, pageRequest);
    }

    @Override
    public Page<ActivitySign> queryUnCommentByActivityId(long activityId, int pageNumber) throws ServiceRuntimeException
    {
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        PageRequest pageRequest = new PageRequest(pageNumber - 1, 20, sort);
        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("activity.id", new SearchFilter("activity.id", SearchFilter.Operator.EQ, activityId));
        filters.put("hasCommnet", new SearchFilter("hasCommnet", SearchFilter.Operator.EQ, DKQConstant.COMMENT_NO));
        Specification<ActivitySign> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivitySign.class);
        return this.activitySignDao.findAll(spec, pageRequest);
    }

    @Override
    public List<ActivitySign> queryAllByActivity(String activityCode) throws ServiceRuntimeException
    {
        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("activity.activityCode", new SearchFilter("activity.activityCode", SearchFilter.Operator.EQ, activityCode));
        Specification<ActivitySign> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivitySign.class);
        return this.activitySignDao.findAll(spec);
    }

    @Override
    public List<ActivitySign> queryAllUnSubmit() throws ServiceRuntimeException
    {
        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("recordId", new SearchFilter("recordId", SearchFilter.Operator.EQ, 0L));
        Specification<ActivitySign> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivitySign.class);
        return this.activitySignDao.findAll(spec);
    }

    @Override
    public Page<ActivitySign> queryByActivity(Long activityId, int pageNumber) throws ServiceRuntimeException
    {
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        PageRequest pageRequest = new PageRequest(pageNumber - 1, 20, sort);

        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("activity.id", new SearchFilter("activity.id", SearchFilter.Operator.EQ, activityId));
        Specification<ActivitySign> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivitySign.class);
        return this.activitySignDao.findAll(spec, pageRequest);
    }

    @Override
    public ActivitySign queryByMemberAndActivity(String memberCode, String activityCode) throws ServiceRuntimeException
    {
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        PageRequest pageRequest = new PageRequest(0, 20, sort);

        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("volunteer.memberCode", new SearchFilter("volunteer.memberCode", SearchFilter.Operator.EQ, memberCode));
        filters.put("activity.activityCode", new SearchFilter("activity.activityCode", SearchFilter.Operator.EQ, activityCode));
        Specification<ActivitySign> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivitySign.class);
        Page<ActivitySign> data = this.activitySignDao.findAll(spec, pageRequest);
        if(null != data)
            return data.getContent().get(0);
        return null;
    }

    @Override
    public ActivitySign queryByMemberAndActivity(Long volunteerId, Long activityId) throws ServiceRuntimeException
    {
        return this.activitySignDao.queryByVolunteerAndActivity(volunteerId,activityId);
    }

    @Override
    public long countByMember(Long volunteerId) throws ServiceRuntimeException
    {
        Long times = activitySignDao.countByMember(volunteerId);
        if(null == times)
            return 0L;
        return times;
    }

    @Override
    public long countByActivity(Long activityId) throws ServiceRuntimeException
    {
        Long times = activitySignDao.countByActivity(activityId);
        if(null == times)
            return 0L;
        return times;
    }

    @Override
    public long countByMemberAnd2Date(Long volunteerId, String startDate, String endDate) throws ServiceRuntimeException
    {
        Long times = activitySignDao.countByMemberAnd2Date(volunteerId,startDate,endDate);
        if(null == times)
            return 0L;
        return times;
    }

    @Override
    public long countByMemberYear(Long volunteerId, String year) throws ServiceRuntimeException
    {
        Long times = activitySignDao.countByMemberYear(volunteerId, year);
        if(null == times)
            return 0L;
        return times;
    }

    @Override
    public long countByMemberMonth(Long volunteerId, String month) throws ServiceRuntimeException
    {
        Long times = activitySignDao.countByMemberMonth(volunteerId, month);
        if(null == times)
            return 0L;
        return times;
    }

    @Override
    public void updateCommentType(Long activitySignId, int type,String memberCode) throws ServiceRuntimeException
    {
        ActivitySign activitySign = this.activitySignDao.findOne(activitySignId);
        if(null != activitySign)
        {
            activitySign.setHasCommnet(DKQConstant.COMMENT_YES);
            activitySign.setCommnetType(type);
            this.activitySignDao.save(activitySign);
        }
    }

    @Override
    public void updateCommentType(String param) throws ServiceRuntimeException
    {
        JSONObject jsonObject = JSON.parseObject(param);
        Long activitySignId = jsonObject.getLong("activitySignId");
        String memberCode = jsonObject.getString("memberCode");
        int type = jsonObject.getIntValue("type");
        this.updateCommentType(activitySignId,type,memberCode);
    }

    @Override
    public long countComments(Long volunteerId, int type) throws ServiceRuntimeException
    {
        Long times = activitySignDao.countComments(volunteerId,type);
        if(null == times)
            return 0L;
        return times;
    }
}
